package JarJunit;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import org.codehaus.jackson.map.ser.FailingSerializer;
import org.junit.runner.Result;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;

import junit.framework.TestFailure;

import org.junit.runner.JUnitCore;
import org.junit.runner.notification.Failure;

import Common.TraceWriter;


public class JarJunitTestRunner {
	
	static final String TEST_OUTPUT_FILE_NAME_PREFIX = "TestResult_";
	static final String CLASS_SUFFIX = ".class";

	public static JarJunitResult run_tests_from_class_in_jar(String jar_file_path, String full_class_name)
	{
		try
		{
			URL url = new File(jar_file_path).toURL();
			URLClassLoader class_loader = new URLClassLoader(new URL[]{url});
			
			if (full_class_name.endsWith(CLASS_SUFFIX))
			{
				//fix class name
				String class_name_with_suffix = full_class_name.replace('/', '.');
				String class_name = class_name_with_suffix.substring(0, class_name_with_suffix.length()-6);
				
				Class testing_class = class_loader.loadClass(class_name);
				
				JUnitCore core = new JUnitCore();
		        Result tests_result = core.run(testing_class);
		        
		        TraceWriter.trace("JarJunitTestRunner: done running all tests in class!");
		        
		        return build_unit_test_result(tests_result);
			}
		}
		catch (MalformedURLException e)
		{
			TraceWriter.trace("error: cant create url for jar loading");
		}
		catch (ClassNotFoundException e)
		{
			TraceWriter.trace("error: can't find class "+full_class_name+" in jar file "+jar_file_path);
			e.printStackTrace();
		}
		
		return new JarJunitResult();
	}
	
	static JarJunitResult build_unit_test_result(Result results)
	{
		JarJunitResult test_result = new JarJunitResult();
		test_result.setTotalNumOfTests(results.getRunCount());
		test_result.setPassedNumOfTests(results.getRunCount()-results.getFailureCount());
		test_result.setFailedNumOfTests(results.getFailureCount());
		List<FailedTestResult> failed_tests = new ArrayList<FailedTestResult>();
		
		List<Failure> fauilres_list = results.getFailures();
		for (Failure failure_instance: fauilres_list)
		{
			FailedTestResult failed_test = new FailedTestResult();
			failed_test.setTestMessage(failure_instance.getMessage());
			failed_test.setTestName(failure_instance.getTestHeader());
			failed_test.setTestTrace(failure_instance.getTrace());
			failed_tests.add(failed_test);
		}
		test_result.setFailedTestsList(failed_tests);
		
		TraceWriter.trace("TEST results: Out of "+test_result.getTotalNumOfTests()+" total: "+test_result.getPassedNumOfTests()+" OK, "+test_result.getFailedNumOfTests()+" failed");
		
		return test_result;
	}

}
